package top.xiaodaiyu.shiro.auth.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.util.SerializationUtils;
import redis.clients.jedis.Jedis;

import java.io.Serializable;
import java.util.*;

/**
 * @author by  Administrator
 * 包名空间  top.xiaodaiyu.shiro.auth.config
 * 用途
 * Created by dtt on 2018/8/2
 * Email 532199946@qq.com
 **/
@Slf4j
public class JedisCache<K, V> implements Cache<K, V>, Serializable {

    private static final String PREFIX = "SHIRO_SESSION_ID";

    private byte[] getByteKey(K k) {
        if (k instanceof String) {
            String key = PREFIX + k;
            return key.getBytes();
        }else if(k instanceof PrincipalCollection) {
            String key = "SHIRO_QUANXIAN_ID";
            return key.getBytes();
        }
        else {
            return SerializationUtils.serialize((Serializable) k);
        }
    }

    @Override
    public V get(K k) throws CacheException {
        log.info("get==========K:"+k);
        if(k==null){
            return null;
        }

        //System.out.println(k);
        Jedis jedis = JedisUtil.getJedis();
        byte[] bytes = jedis.get(getByteKey(k));
        JedisUtil.closeJedis(jedis);
        if(bytes==null){
            return null;
        }
        return (V) SerializationUtils.deserialize(bytes);
    }

    @Override
    public V put(K k, V v) throws CacheException {
        log.info("put=====K:"+k+"====V:"+v);
        Jedis jedis = JedisUtil.getJedis();
        jedis.set(getByteKey(k), SerializationUtils.serialize((Serializable) v));
        jedis.expire(getByteKey(k),10000);
        byte[] bytes = jedis.get(SerializationUtils.serialize(getByteKey(k)));
        JedisUtil.closeJedis(jedis);
        if(bytes==null){
            return null;
        }
        return (V) SerializationUtils.deserialize(bytes);
    }

    @Override
    public V remove(K k) throws CacheException {
        log.info("remove========");
        Jedis jedis = JedisUtil.getJedis();
        byte[] bytes = jedis.get(getByteKey(k));
        jedis.del(getByteKey(k));
        JedisUtil.closeJedis(jedis);
        if(bytes==null){
            return null;
        }
        return (V) SerializationUtils.deserialize(bytes);
    }

    @Override
    public void clear() throws CacheException {
        log.info("clear========");
        JedisUtil.getJedis().flushDB();
    }

    @Override
    public int size() {
        log.info("size========");
        Jedis jedis = JedisUtil.getJedis();
        Long size = jedis.dbSize();
        return size.intValue();
    }

    @Override
    public Set<K> keys() {
        log.info("Set========");
        Jedis jedis = JedisUtil.getJedis();
        Set<byte[]> bytes = jedis.keys((PREFIX + new String("*")).getBytes());
        Set<K> keys = new HashSet<>();
        if (bytes != null) {
            for (byte[] b : bytes) {
                keys.add((K) SerializationUtils.deserialize(b));
            }
        }
        JedisUtil.closeJedis(jedis);
        return keys;
    }

    @Override
    public Collection<V> values() {
        log.info("Collection========");
        Set<K> keys = this.keys();
        Jedis jedis = JedisUtil.getJedis();
        List<V> lists = new ArrayList<>();
        for (K k : keys) {
            byte[] bytes = jedis.get(getByteKey(k));
            lists.add((V) SerializationUtils.deserialize(bytes));
        }
        JedisUtil.closeJedis(jedis);
        return lists;
    }
}
